<template>
  <div id="tags-view-container" class="tags-view-container">
    <!-- <scroll-pane ref="scrollPane" class="tags-view-wrapper"> -->
    <div class="tags-view-wrapper">
      <router-link
        v-for="tag in visitedViews"
        ref="tag"
        :key="tag.path"
        :class="isActive(tag) ? 'active' : ''"
        :to="{ path: tag.path, query: tag.query, fullPath: tag.fullPath }"
        tag="span"
        class="tags-view-item"
        @click.middle="closeSelectedTag(tag)"
        @contextmenu.prevent="openMenu(tag, $event)"
      >
        {{ tag.title }}
        <el-icon
          v-if="!tag.meta.affix"
          @click.prevent.stop="closeSelectedTag(tag)"
          class="close-icon"
          ><Close
        /></el-icon>
      </router-link>
    </div>
    <ul
      v-show="tagForm.visible"
      :style="{ left: tagForm.left + 'px', top: tagForm.top + 'px' }"
      class="contextmenu"
    >
      <li
        v-if="!isAffix(tagForm.selectedTag)"
        @click="closeSelectedTag(tagForm.selectedTag)"
      >
        关闭
      </li>
      <li @click="closeOthersTags">关闭其他</li>
      <li @click="closeAllTags(tagForm.selectedTag)">关闭所有</li>
    </ul>
  </div>
</template>

<script lang="ts" setup>
import { TagviewStore } from "@/stores/moudles/tagview";
import { useRouter, RouteRecordRaw } from "vue-router";
import { TagViewProps } from "@/stores/interface";
import { computed, nextTick, ref, watch, reactive, onBeforeMount } from "vue";

const tagForm = reactive({
  visible: false,
  top: 0,
  left: 0,
  selectedTag: {},
  affixTags: [],
});
const router = useRouter();

const Tagroutes = computed(() => {
  return [
    {
      path: "/BigScreen",
      name: "BigScreen",
      meta: {
        icon: "HomeFilled",
        title: "首页",
        affix: true,
        noCache: true,
      },
    },
  ];
});
onBeforeMount(() => {
  initTags();
  addTags();
});
watch(
  () => router.currentRoute.value,
  () => {
    if (router.currentRoute.value.name !== "login") {
      addTags();
      moveToCurrentTag();
    }
  },
  { deep: true }
);
watch(
  () => tagForm.visible,
  () => {
    if (tagForm.visible) {
      document.body.addEventListener("click", closeMenu);
    } else {
      document.body.removeEventListener("click", closeMenu);
    }
  },
  { deep: true }
);
const tag = ref();
const tagviewStore = TagviewStore();

const visitedViews = computed(() => tagviewStore.visitedViews);
const cachedViews = computed(() => tagviewStore.cachedViews);

const isActive = (route) => {
  return route.path === router.currentRoute.value.path;
};
const isAffix = (tag) => {
  return tag.meta && tag.meta.affix;
};
const filterAffixTags = (routes, basePath = "/") => {
  let tags = [];
  routes.value.forEach((route) => {
    if (route.meta && route.meta.affix) {
      tags.push({
        path: route.path,
        name: route.name,
        meta: { ...route.meta },
      });
    }
    if (route.children) {
      const tempTags = filterAffixTags(route.children, route.path);
      if (tempTags.length >= 1) {
        tags = [...tags, ...tempTags];
      }
    }
  });

  return tags;
};
const initTags = () => {
  tagForm.affixTags = filterAffixTags(Tagroutes);

  for (const tag of tagForm.affixTags) {
    if (tag.name) {
      tagviewStore.AddVisitedView(tag as TagViewProps);
    }
  }
};
const addTags = () => {
  const { name } = router.currentRoute.value;
  if (name) {
    tagviewStore.AddVisitedView(router.currentRoute.value as TagViewProps);
    tagviewStore.AddCachedView(router.currentRoute.value as TagViewProps);
  }
  return false;
};
const moveToCurrentTag = () => {
  const tags = tag;

  nextTick(() => {
    for (const tag of tags.value) {
      if (tag.to.path === router.currentRoute.value.path) {
        if (tag.to.fullPath !== router.currentRoute.value.fullPath) {
          tagviewStore.UpdateVisitedView(
            router.currentRoute.value as TagViewProps
          );
        }
        break;
      }
    }
  });
};
const closeSelectedTag = (view) => {
  if (tagviewStore.visitedViews.length == 1) {
    return false;
  }
  /*  if (view.path.includes("Info")) {
    router.go(-1); //返回上一页
    return false;
  } */
  new Promise((resolve) => {
    tagviewStore.DelVisitedView(view as TagViewProps);
    tagviewStore.DelCachedView(view as TagViewProps);
    resolve({
      visitedViews: [...tagviewStore.visitedViews],
      cachedViews: [...tagviewStore.cachedViews],
    });
  }).then(({ visitedViews }) => {
    if (isActive(view)) {
      toLastView(visitedViews, view);
    }
  });
};
const closeOthersTags = () => {
  router.push(tagForm.selectedTag);
  new Promise((resolve) => {
    tagviewStore.DelOthersVisitedViews(tagForm.selectedTag as TagViewProps);
    tagviewStore.DelOthersCachedViews(tagForm.selectedTag as TagViewProps);
    resolve({});
  }).then(() => {
    moveToCurrentTag();
  });
};
const closeAllTags = (view) => {
  new Promise((resolve) => {
    tagviewStore.DelAllVisitedViews(view);
    tagviewStore.DelAllCachedViews(view);
    resolve({
      visitedViews: [...tagviewStore.visitedViews],
      cachedViews: [...tagviewStore.cachedViews],
    });
  }).then(({ visitedViews }) => {
    if (tagForm.affixTags.some((tag) => tag.path === view.path)) {
      return;
    }
    toLastView(visitedViews, view);
  });
};
const toLastView = (visitedViews, view) => {
  const latestView = visitedViews.slice(-1)[0];
  if (latestView) {
    router.push(latestView);
  } else {
    if (view.name === "BigScrenn") {
      router.replace({ path: "/redirect" + view.fullPath });
    } else {
      router.push("/");
    }
  }
};
const openMenu = (tag, e) => {
  tagForm.top = e.clientY;
  tagForm.left = e.clientX;
  tagForm.visible = true;
  tagForm.selectedTag = tag;
};
const closeMenu = () => {
  tagForm.visible = false;
};
</script>

<style scoped lang="scss">
@import "./index.scss";
</style>
